using System;
using System.Text;
using System.Collections;
using InfoJetSoft.Service.XPath;

//CID 0164 //2008.12.13 //Begin
namespace InfoJetSoft.Service.XPath.Exprs
{
	/// <summary>
	/// Summary description for UnaryExpr.
	/// </summary>
    public class UnaryExpr : IExpr
	{
		private int _negativeCount = 0;
		private IExpr _union = null;

		public UnaryExpr()
		{
			//
			// TODO: Add constructor logic here
			//
        }

        public int NegativeCount
        {
            get
            {
                return this._negativeCount;
            }
        }

        public IExpr Union
        {
            get
            {
                return this._union;
            }
        }

        public object Evaluate(ExprContext context)
        {
            //CID 0805 //2011.02.26 //Begin
            object result = this._union.Evaluate(context);
            double value = NumberFunctions.number(context, result);
            if (this._negativeCount % 2 == 0)
            {
                return value;
            }
            else
            {
                return -value;
            }
            //CID 0805 //2011.02.26 //End
        }

        //CID 0866 //2011.04.01 //Begin
        public void Visit(IExprVisitor visitor)
        {
            this._union.Visit(visitor);
        }
        //CID 0866 //2011.04.01 //End

        public void Print(StringBuilder buffer)
        {
            for (int i = 0; i < this._negativeCount; i++)
            {
                buffer.Append("-");
            }
            this._union.Print(buffer);
        }

        public static IExpr Parse(ExprParser parser)
		{
			int negativeCount = 0;
            OperatorExpr unaryOperator = OperatorExpr.parseUnaryOperator(parser);
			while( unaryOperator != null )
			{
				negativeCount++;
				
				unaryOperator = OperatorExpr.parseUnaryOperator( parser );
			}
			
			IExpr unionExpr = UnionExpr.Parse( parser );
            if (unionExpr != null)
            {
                if (negativeCount > 0)
                {
                    UnaryExpr unaryExpr = new UnaryExpr();
                    unaryExpr._negativeCount = negativeCount;
                    unaryExpr._union = unionExpr;
                    return unaryExpr;
                }
                else
                {
                    return unionExpr;
                }
            }
            else
            {
                if (negativeCount > 0)
                {
                    throw new Exception("Cannot parse " + parser.XPath);
                }
            }
			return null;
		}
	}
}
//CID 0164 //2008.12.13 //End
